package nl.ejvos.bgpgames.tictactoe.server;

import nl.ejvos.bgpgames.tictactoe.shared.ClickedMessage;
import nl.ejvos.bgpgames.tictactoe.shared.Constants;
import nl.ejvos.bgpgames.tictactoe.shared.EntireStateMessage;
import nl.ejvos.bgpgames.tictactoe.shared.RestartMessage;

import com.hu.bgp.framework.GameStateListener;
import com.hu.bgp.framework.Player;
import com.hu.bgp.framework.Server;
import com.hu.bgp.framework.clientapi.ClientToServerMessage;
import com.hu.bgp.server.GameContext;

/**
 * Game logica van boter, kaas & eieren.
 * 
 * @author ejvos
 */
public class TicTacToeServer extends Server
{
	public TicTacToeServer(GameContext gameContext) {
		super(gameContext);
		restart();
	}

	private int gameStatus;
	private int[][] tileStatus = {
			{ Constants.tsAny, Constants.tsAny, Constants.tsAny },
			{ Constants.tsAny, Constants.tsAny, Constants.tsAny },
			{ Constants.tsAny, Constants.tsAny, Constants.tsAny } };

	private void doTurn() {
		if (gameStatus == Constants.gsCrossPlaying
				|| gameStatus == Constants.gsNoughtPlaying) {
			// check for a winner
			boolean winner = false;

			for (int k = 0; k < 8; k++) {
				boolean success = true;
				boolean found = false;

				for (int i = 0; i < 3; i++) {
					success = success
							&& (tileStatus[Constants.rowWins[k][i]][Constants.colWins[k][i]] == (gameStatus == Constants.gsNoughtPlaying ? Constants.tsNought
									: Constants.tsCross));
					found = found
							|| (tileStatus[Constants.rowWins[k][i]][Constants.colWins[k][i]] == (gameStatus == Constants.gsNoughtPlaying ? Constants.tsNought
									: Constants.tsCross));
				}

				if (success && found) {
					// somebody won
					winner = true;
					break;
				}
			}
			if (winner) {
				gameStatus = gameStatus == Constants.gsCrossPlaying ? Constants.gsCrossWon
						: Constants.gsNoughtWon;
			} else {
				// check for draw
				boolean emptyFound = false;
				for (int j = 0; j < 3; j++)
					for (int k = 0; k < 3; k++)
						if (tileStatus[j][k] == Constants.tsAny)
							emptyFound = true;

				if (!emptyFound) {
					gameStatus = Constants.gsNobodyWon;
				} else {
					// nobody won and still tiles open, keep the game going
					if (gameStatus == Constants.gsCrossPlaying) {
						gameStatus = Constants.gsNoughtPlaying;
					} else if (gameStatus == Constants.gsNoughtPlaying) {
						gameStatus = Constants.gsCrossPlaying;
					}
				}
			}
		}
	}

	public void clickTile(int x, int y) {
		if (tileStatus[x][y] == Constants.tsAny) {
			if (gameStatus == Constants.gsCrossPlaying) {
				tileStatus[x][y] = Constants.tsCross;
			} else if (gameStatus == Constants.gsNoughtPlaying) {
				tileStatus[x][y] = Constants.tsNought;
			}
			doTurn();
			updateAllClients();
		}
	}

	public void restart() {
		gameStatus = Constants.gsCrossPlaying;
		for (int j = 0; j < 3; j++) {
			for (int k = 0; k < 3; k++) {
				tileStatus[j][k] = Constants.tsAny;
			}
		}
	}

	public void handleMessage(ClientToServerMessage message) {
		if (message instanceof ClickedMessage) {
			ClickedMessage clickedMessage = (ClickedMessage) message;
			clickTile(clickedMessage.getX(), clickedMessage.getY());
		} else if (message instanceof RestartMessage) {
			restart();
			updateAllClients();
		}
	}

	private void updateAllClients() {
		EntireStateMessage message = new EntireStateMessage(gameStatus,
				tileStatus);
		broadcastMessage(message);
	}

	public void addPlayer(Player player) {
		// TODO Auto-generated method stub
		
	}

	public void removePLayer(Player player) {
		// TODO Auto-generated method stub
		
	}

}
